package com.ltcode.auth.infrastructure.repository.impl;

import com.ltcode.auth.domain.model.Captcha;
import com.ltcode.auth.domain.repository.CaptchaRepository;
import com.ltcode.cache.service.RedisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 验证码仓储实现
 * 
 * @author ltcode
 * @since 2024-01-01
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class CaptchaRepositoryImpl implements CaptchaRepository {

    private final RedisService redisService;

    private static final String CAPTCHA_KEY_PREFIX = "auth:captcha:";
    private static final long DEFAULT_EXPIRE_MINUTES = 5; // 默认5分钟过期

    @Override
    public Captcha save(Captcha captcha) {
        try {
            String key = getCaptchaKey(captcha.getUuid());
            redisService.setCacheObject(key, captcha, DEFAULT_EXPIRE_MINUTES, TimeUnit.MINUTES);
            log.debug("保存验证码成功: uuid={}", captcha.getUuid());
            return captcha;
        } catch (Exception e) {
            log.error("保存验证码失败: uuid={}", captcha.getUuid(), e);
            throw new RuntimeException("保存验证码失败", e);
        }
    }

    @Override
    public Optional<Captcha> findByUuid(String uuid) {
        try {
            String key = getCaptchaKey(uuid);
            Captcha captcha = redisService.getCacheObject(key);
            return Optional.ofNullable(captcha);
        } catch (Exception e) {
            log.error("查询验证码失败: uuid={}", uuid, e);
            return Optional.empty();
        }
    }

    @Override
    public void deleteByUuid(String uuid) {
        try {
            String key = getCaptchaKey(uuid);
            redisService.deleteObject(key);
            log.debug("删除验证码成功: uuid={}", uuid);
        } catch (Exception e) {
            log.error("删除验证码失败: uuid={}", uuid, e);
        }
    }

    @Override
    public void updateUsedStatus(String uuid, boolean used) {
        try {
            Optional<Captcha> captchaOpt = findByUuid(uuid);
            if (captchaOpt.isPresent()) {
                Captcha captcha = captchaOpt.get();
                captcha.setUsed(used);
                save(captcha);
                log.debug("更新验证码使用状态成功: uuid={}, used={}", uuid, used);
            }
        } catch (Exception e) {
            log.error("更新验证码使用状态失败: uuid={}, used={}", uuid, used, e);
        }
    }

    @Override
    public void incrementFailCount(String uuid) {
        try {
            Optional<Captcha> captchaOpt = findByUuid(uuid);
            if (captchaOpt.isPresent()) {
                Captcha captcha = captchaOpt.get();
                captcha.incrementFailCount();
                save(captcha);
                log.debug("增加验证码失败次数成功: uuid={}, failCount={}", uuid, captcha.getFailCount());
            }
        } catch (Exception e) {
            log.error("增加验证码失败次数失败: uuid={}", uuid, e);
        }
    }

    @Override
    public boolean existsByUuid(String uuid) {
        try {
            String key = getCaptchaKey(uuid);
            return redisService.hasKey(key);
        } catch (Exception e) {
            log.error("检查验证码是否存在失败: uuid={}", uuid, e);
            return false;
        }
    }

    @Override
    public void cleanExpiredCaptchas() {
        try {
            // Redis的过期机制会自动清理过期的验证码
            log.debug("清理过期验证码完成");
        } catch (Exception e) {
            log.error("清理过期验证码失败", e);
        }
    }

    @Override
    public long countByType(Captcha.CaptchaType type) {
        try {
            // 这里可以实现统计逻辑，暂时返回0
            return 0;
        } catch (Exception e) {
            log.error("统计验证码数量失败: type={}", type, e);
            return 0;
        }
    }

    @Override
    public void setExpireTime(String uuid, int expireMinutes) {
        try {
            String key = getCaptchaKey(uuid);
            redisService.expire(key, expireMinutes, TimeUnit.MINUTES);
            log.debug("设置验证码过期时间成功: uuid={}, expireMinutes={}", uuid, expireMinutes);
        } catch (Exception e) {
            log.error("设置验证码过期时间失败: uuid={}, expireMinutes={}", uuid, expireMinutes, e);
        }
    }

    private String getCaptchaKey(String uuid) {
        return CAPTCHA_KEY_PREFIX + uuid;
    }
}
